from typing import Tuple

from lucommon.logger import lu_logger

import agent
import conf
from async_task.services import register_job, AsyncTask
from deploy.services import docker as DOCKER
from utils import gen_static_dir, get_static_url, concurrence_requests, clean_path
from . import check_agent_status, check_concurrence_result


class AsyncTaskDeployDocker(AsyncTask):
    def task_impl(self, nodes, pkg, application_dir, docker_service_path) -> Tuple[int, any]:
        request_infos = {
            str(ip): {
                "url": "http://{}:{}{}".format(ip, agent.AGENT_PORT, agent.INSTALL_DOCKER),
                "method": "POST",
                "json": {
                    "pkg_url": {"url": pkg.url, "extract_type": pkg.extract_type, "save_path": ""},
                    "application_dir": application_dir,
                    "depend_files": [
                        {
                            "url": get_static_url(docker_service_path),
                            "save_path": clean_path("{}/{}".format(conf.SERVICE_DIR, DOCKER.DOCKER_SERVER_NAME))
                        },  # service file
                    ],
                }
            }
            for ip in nodes
        }
        lu_logger.debug("request_infos:{}".format(request_infos))
        docker_result = concurrence_requests(request_infos)
        if check_concurrence_result(docker_result):
            return 0, docker_result
        return -1, docker_result


def job_deploy_docker(params):
    hosts = params["hosts"]
    application_dir = params["application_dir"]
    work_dir = params["work_dir"]
    insecure_registry_list = params["insecure_registry_list"]
    dns_list = params["dns_list"]
    version = params["version"]

    pkg = conf.DOCKER_PACKAGE.get(str(version))
    if not pkg:
        return -1, "无适用的docker package,valid_version:{}".format(",".join(list(conf.DOCKER_PACKAGE.keys()))), {}

    # 检查agent状态
    err_ips = check_agent_status(hosts)
    if err_ips:
        return -1, "节点检查失败,{}".format(",".join(err_ips)), {}

    # 生成service存放目录
    static_dir = gen_static_dir()
    lu_logger.debug("conf dir:{}".format(static_dir))

    # 生成docker.service
    docker_service_path = DOCKER.gen_docker_service(static_dir, work_dir, insecure_registry_list, dns_list)

    job = register_job(
        "部署docker",
        [
            [
                AsyncTaskDeployDocker(
                    "部署docker",
                    {
                        "nodes": hosts,
                        "pkg": pkg,
                        "application_dir": application_dir,
                        "docker_service_path": docker_service_path,
                    }
                ),
            ]
        ]
    )

    data = {
        "docker_service_path": get_static_url(docker_service_path),
        "job_id": job.id,
    }

    return 0, "", data
